#pragma once
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <fstream>
#include <iostream>
#include "ImplicitBuilder.h"
#include "GridGenerator.h"

/**
 * @brief 网格边类
 */
struct Edge {
    size_t v1, v2;  // 顶点索引

    // 添加默认构造函数
    Edge() : v1(0), v2(0) {}

    Edge(size_t v1_, size_t v2_) 
        : v1(std::min(v1_, v2_)), v2(std::max(v1_, v2_)) {}

    bool operator==(const Edge& other) const {
        return v1 == other.v1 && v2 == other.v2;
    }

    // 添加小于运算符，用于排序
    bool operator<(const Edge& other) const {
        return v1 < other.v1 || (v1 == other.v1 && v2 < other.v2);
    }
};

// Edge的哈希函数
namespace std {
    template<>
    struct hash<Edge> {
        size_t operator()(const Edge& e) const {
            return hash<size_t>()(e.v1) ^ (hash<size_t>()(e.v2) << 1);
        }
    };
}

// 用于unordered_map的pair哈希函数
struct PairHash {
    template <class T1, class T2>
    std::size_t operator () (const std::pair<T1, T2>& p) const {
        auto h1 = std::hash<T1>{}(p.first);
        auto h2 = std::hash<T2>{}(p.second);
        return h1 ^ (h2 << 1);
    }
};

/**
 * @brief 网格切割器类
 */
class MeshCutter {
public:
    MeshCutter(const std::vector<Point3D>& nodes, 
               const std::vector<Tetrahedron>& elements,
               double gridSize,
               int lastStrataType)
        : nodes_(nodes), elements_(elements), gridSize_(gridSize), 
          lastStrataType_(lastStrataType) {}

    // 处理界面
    void processSurface(const std::vector<std::shared_ptr<ImplicitSurface>>& surfaces, int surfaceType);

    // 重载原有的单界面处理方法
    void processSurface(const ImplicitSurface& surface, int surfaceType);

    // 获取当前网格
    const std::vector<Point3D>& getNodes() const { return nodes_; }
    const std::vector<Tetrahedron>& getElements() const { return elements_; }

    // 添加预处理方法
    void preprocessStrataInterface(const ImplicitSurface& surface, int surfaceType);

private:
    std::vector<Point3D> nodes_;
    std::vector<Tetrahedron> elements_;
    double gridSize_;
    
    // 添加成员变量
    std::unordered_set<Edge> edges_;
    std::unordered_map<Edge, std::vector<size_t>> edgeToTets_;
    
    struct Stats {
        int cutEdges = 0;
        int newNodes = 0;
        int newTets = 0;
        float time = 0.0f;
    };
    std::unordered_map<int, Stats> stats_;

    // 找到活动边
    std::vector<std::pair<size_t, size_t>> findActiveEdges(
        const ImplicitSurface& surface,
        int surfaceType);  // 移除const，添加surfaceType参数

    // 计算切割点
    std::unordered_map<std::pair<size_t, size_t>, size_t, PairHash> 
    computeCutPoints(const std::vector<std::pair<size_t, size_t>>& activeEdges,
                    const ImplicitSurface& surface,
                    int surfaceType);  // 添加surfaceType参数

    // 切割四面体
    void splitTetrahedra(
        const std::unordered_map<std::pair<size_t, size_t>, size_t, PairHash>& cutPoints,
        int surfaceType);  // 添加surfaceType参数

    // 检查点是否在界面上
    bool isPointOnSurface(const Point3D& p, const ImplicitSurface& surface) const;

    // 计算边的切割点
    Point3D computeCutPoint(const Point3D& p1, const Point3D& p2, 
                          const ImplicitSurface& surface) const;

    // 辅助函数：计算四面体的切割模式
    int computeCutPattern(
        const Tetrahedron& tet,
        const std::unordered_map<std::pair<size_t, size_t>, size_t, PairHash>& cutPoints) const;

    // 根据切割模式生成新的四面体
    std::vector<Tetrahedron> generateNewTetrahedra(
        const Tetrahedron& tet,
        const std::unordered_map<std::pair<size_t, size_t>, size_t, PairHash>& cutPoints,
        int pattern) const;

    // 四面体切割相关函数
    std::vector<Tetrahedron> splitCaseA(const Tetrahedron& tet, 
        const std::unordered_map<Edge, size_t>& cuts) const;
    std::vector<Tetrahedron> splitCaseB(const Tetrahedron& tet,
        const std::unordered_map<Edge, size_t>& cuts) const;
    std::vector<Tetrahedron> splitCaseC(const Tetrahedron& tet,
        const std::unordered_map<Edge, size_t>& cuts) const;
    std::vector<Tetrahedron> splitCaseD(const Tetrahedron& tet,
        const std::unordered_map<Edge, size_t>& cuts) const;

    // 添加其他辅助函数
    void buildEdges();
    void buildEdgeToTets();
    void updateMeshData();
    bool isCoplanar(const std::vector<Point3D>& points) const;
    bool checkCoplanar(const std::vector<Point3D>& points) const;
    std::unordered_set<Edge> buildEdgesForTet(const Tetrahedron& tet) const;
    std::vector<size_t> findTetsForEdge(const Edge& edge) const;
    void splitTets(const std::unordered_map<Edge, size_t>& cutPoints, int surfaceType);

    // 完全禁用日志输出
    void debug_log(const std::string&) const {}
    void debug_log(const std::string&, double) const {}
    void debug_log(const std::string&, int) const {}
    void debug_log(const std::string&, size_t) const {}

    // 添加getEdgeIndex函数声明
    int getEdgeIndex(const Edge& edge) const;

    // 添加最后一个地层界面类型
    int lastStrataType_;
    
    // 添加辅助函数声明
    bool isEdgeInBounds(const Point3D& p1, const Point3D& p2,
                       const Point3D& boundsMin, const Point3D& boundsMax) const;

    // 添加辅助方法
    bool isVerticalEdge(const Point3D& p1, const Point3D& p2) const;
    bool canProcessEdge(const Point3D& p1, const Point3D& p2, int surfaceType) const;
    void updateNodeToIntersection(size_t nodeIndex, const Point3D& intersection, int surfaceType);

    // 添加新的辅助函数
    bool isValidTetrahedron(const Tetrahedron& tet) const;
}; 